package com.sinodata.bsm.center.engine.event.worker;

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import com.sinodata.bsm.center.cache.EventRuleCache;
import com.sinodata.bsm.center.cache.EventTypeCache;
import com.sinodata.bsm.center.engine.event.EventWorker;
import com.sinodata.bsm.center.service.event.EventService;
import com.sinodata.bsm.center.util.spring.SpringContextHolder;
import com.sinodata.bsm.common.constants.EventConstants;
import com.sinodata.bsm.common.vo.Event;
import com.sinodata.bsm.common.vo.EventRule;
import com.sinodata.bsm.common.vo.EventType;

/**
 * 
 * <p>
 * Description: 事件处理工作流：事件过滤
 * </p>
 *
 * @author liulibo
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-5-29 AM 10:16:26    liulibo        1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public class EventFiltWorker implements EventWorker {

    private static final Logger logger = Logger.getLogger(EventFiltWorker.class);

    private static Map<String, FilterItem> times = new HashMap<String, FilterItem>();

    private static EventTypeCache eventTypeCache = SpringContextHolder.getBean(EventTypeCache.class);

    private static EventRuleCache eventRuleCache = SpringContextHolder.getBean(EventRuleCache.class);

    private static EventService eventService = SpringContextHolder.getBean(EventService.class);

    public EventFiltWorker() {
        Collections.synchronizedMap(times);
    }

    @Override
    public void execute(Event event) {
        EventType eventType = eventTypeCache.get(event.getEventTypeId());
        if (eventType.getRecoverable() == EventConstants.TYPE_RECOVERABLE) {
            return;
        }
        Long resId = event.getResId();
        Long typeId = event.getEventTypeId();
        List<EventRule> eventRules = eventRuleCache.getAvailableFilterRule(resId, typeId, event.getLevel());
        if (eventRules == null || eventRules.size() == 0) {
            return;
        }
        //TODO 判断有效时间范围
        for (EventRule eventRule : eventRules) {
            String content = eventRule.getKeyWord();
            content = content == null ? "" : content.trim();
            String key = eventRule.getResId() + "&" + eventRule.getEventTypeId() + "&" + eventRule.getFilterDuration() + "&" + content;
            if (!times.containsKey(key)) {
                FilterItem item = new FilterItem(event.getId(), event.getOccurTime());
                times.put(key, item);
                return;
            }
            FilterItem item = times.get(key);
            if (event.getOccurTime().getTime() - item.getTime().getTime() > eventRule.getFilterDuration() * 1000L) {
                item = new FilterItem(event.getId(), event.getOccurTime());
                times.put(key, item);
                return;
            } else {
                //过滤内容为空,全部过滤
                if ("".equals(content)) {
                    try {//事件被过滤时 确认人 记录的是事件ID
                         //FascadeUtil.getCenterEventFascade().confirmEvent(eventValue, EventConstants.CONFIRM_TYPE_FILTER, "" + item.getEventId(), "被过滤");
                        eventService.confirm(event.getId(), EventConstants.CONFIRM_TYPE_FILTER, item.getEventId() + "", EventConstants.REMARKER_SYSTEM, "被过滤", true);
                    } catch (Exception e) {//AppException
                        //确认过滤事件失败
                        logger.error("failed to confirm filter event ", e);
                    }
                } else if (filt(event.getMsg(), content)) {
                    //过滤内容不为空,如果事件消息包含过滤内容,执行过滤
                    try {//事件被过滤时 确认人 记录的是事件ID
                         // FascadeUtil.getCenterEventFascade().confirmEvent(eventValue, EventConstants.CONFIRM_TYPE_FILTER, "" + item.getEventId(), "被过滤");
                        eventService.confirm(event.getId(), EventConstants.CONFIRM_TYPE_FILTER, item.getEventId() + "", EventConstants.REMARKER_SYSTEM, "被过滤", true);
                    } catch (Exception e) {//AppException
                        //确认过滤事件失败
                        logger.error("failed to confirm filter event ", e);
                    }
                }
            }

        }
    }

    /**
     * 事件过滤规则过滤内容，先按正则表达式判断
     * 
     * @param msg
     * @param content
     * @return
     */
    private boolean filt(String msg, String content) {
        boolean ret = false;
        try {
            Pattern pattern = Pattern.compile(content);
            ret = pattern.matcher(msg).find();
        } catch (Exception e) {
            ret = msg.contains(content);
        }
        return ret;
    }

    class FilterItem {

        private Long eventId;

        private Date time;

        FilterItem(Long eventId, Date time) {
            this.eventId = eventId;
            this.time = time;
        }

        public Long getEventId() {
            return eventId;
        }

        public void setEventId(Long eventId) {
            this.eventId = eventId;
        }

        public Date getTime() {
            return time;
        }

        public void setTime(Date time) {
            this.time = time;
        }

    }
}
